$def with (page, edition=None)

$ component_times = {}
$ component_times['TotalTime'] = time()

$ tab = input(tab=None).tab
$ editions = []
$ page_type = page.key.split('/')[1]

$ work = page if page.key.startswith('/works') else list(page.works)[0]
$ edition = storage({})

$ component_times['get_sorted_editions'] = time()
$ editions = work.get_sorted_editions()
$ component_times['get_sorted_editions'] = time() - component_times['get_sorted_editions']

$ previews = [e for e in editions if e.get('ocaid')]

$if page.key.startswith('/books'):
  $ edition = page
$elif editions:
  $ edition = editions[0]
  $# edition selection strategy (e.g. language, by id, first w/ ocaid)
  $ selected_ocaid = query_param('edition')
  $for e in editions:
    $if e.get('ocaid'):
      $if not selected_ocaid or selected_ocaid == e.get('ocaid'):
        $ edition = e

$ ocaid = edition.get('ocaid')
$ book_title = edition.get('title', '') or (work.title if work else '')
$ work_title = work.title if work else edition.get('title', '')
$ book_subtitle = edition.get('subtitle', '')
$ title_suffix = cond(edition.get('publish_date'), u"({0} edition)".format(edition.get('publish_date')), "(edition)")
$ title = book_title + " " + title_suffix
$ title_with_site = _("%(page_title)s | Open Library", page_title=title)
$ book_description = (edition and edition.description) or (work and work.description)
$ edition_count = work.edition_count if work and work.edition_count else 1
$ meta_cover_url = item_image((edition or work).get_cover_url("L"), default="https://openlibrary.org/images/icons/avatar_book-sm.png")
$ _x = ctx.setdefault('bodyid', 'book')

$var title: $title

$code:
    def has_any(*keys):
        return any(page[k] for k in keys)

$code:
    def get_description(book):
        if book.publishers and book.publish_date:
            ed_info = book.publish_date + ', ' + ', '.join(book.publishers)
        elif book.publish_date:
            ed_info = book.publish_date
        elif book.publishers:
            ed_info = ', '.join(book.publishers)
        else:
            ed_info = 'unknown'

        title = cond(work, work.title, book.title)
        authors = cond(work, work and work.get_authors(), book.get_authors())
        author_info = " by " + ", ".join(a.name for a in authors)

        format = ""
        if book.physical_format:
            format += book.physical_format.replace('[', '').replace(']', '')

        if book.languages:
            format += ' in ' + ', '.join(lang.name for lang in book.languages)
        if book.edition_name:
            format += " - " + book.edition_name

        meta = title + author_info + ", " + ed_info + " edition, " + format
        return meta
    description = get_description(page)
    putctx("description", description)

$code:
    def get_authors_byline(page, include_schema=False):
        schema_attribute = cond(include_schema, ' itemprop="author"', '')
        authors = cond(work, work and work.get_authors(), edition and edition.get_authors())
        if authors:
            return ', '.join('<a href="%s"%s>%s</a>' % (a.url(), schema_attribute, truncate(a.name, 40)) for a in authors)
        elif edition.author_names:
            return ('<span%s>' % (schema_attribute)) + ", ".join(edition.author_names) + "</span>"
        else:
            return None

$def display_value(label, value, itemprop=None):
    $if value:
        <dt>$label</dt>
        $if itemprop:
            <dd itemprop="$itemprop" class="object">$:thingrepr(value)</dd>
        $else:
            <dd class="object">$:thingrepr(value)</dd>

$def display_identifiers(label, ids, itemprop=None):
    $if label != "Goodreads":
        $ all_ids = [-1!=id['value'].find('openlib-') for id in ids]
        $if (True in all_ids) and (1==len(all_ids)):
            $return

        <!-- FIXME: Identifier names need to be translated (I18N) -->
        <dt>$label</dt>
        <dd class="object" $:cond(itemprop, 'itemprop="%s"' % itemprop, '')>
            $for id in ids:
                $ sep = cond(loop.last, "", ", ")
                $if -1 != id.value.find('openlib-'):
                    $continue
                $if id.url:
                    <a href="$id.url$('?tag=' + affiliate_id('amazon') if 'amazon.' in id.url else '')">$id.value</a>$sep
                $else:
                    ${id.value}$sep
        </dd>

$def display_goodreads(label, ids):
    $if label == "Goodreads":
        <dt>$label</dt>
        $for id in ids:
            <dd><a href="$id.url">$id.value</a></dd>

$def display_contributor(c):
    <li><span>$c.role</span><br />$c.name </li>

$ authors_byline = get_authors_byline(page, include_schema=True)

$:macros.Metatags(title=title_with_site, image=meta_cover_url, description=description)
$set_share_links(url=request.canonical_url, title=title, view_context=ctx)

$if ctx.user and (ctx.user.is_admin() or ctx.user.is_librarian()):
  $:render_template("type/edition/admin_bar", work, edition, ocaid)

<div id="contentBody" role="main" itemscope itemtype="https://schema.org/Book">
  <div class="workDetails">
    $if work:
        <link itemprop="exampleOfWork" href="$work.key">

    <div class="editionCover">
      $ component_times['databarWork'] = time()
      $:macros.databarWork(edition or work, editions_page=True)
      $ component_times['databarWork'] = time() - component_times['databarWork']
    </div>

    <div class="editionAbout">
      <div class="editionAll">
        $ component_times['EditTopbar'] = time()
        $:macros.databarView(page, edition)
        $ component_times['EditTopbar'] = time() - component_times['EditTopbar']
      </div>

      <div class="work-line">
        $_("An edition of") <a href="$work.key?edition=$(ocaid)">$work_title</a>
        $if work.first_publish_year:
          ($work.first_publish_year)
      </div>

      $:render_template("type/edition/book_title", work, edition)

      $if authors_byline:
        $# authors_byline susceptible to xss!
        <h2 class="edition-byline">$_("by") $:authors_byline</h2>

      $ component_times['ReadlogStats'] = time()
      $:macros.StarRatingsStats(work)
      $ component_times['ReadlogStats'] = time() - component_times['ReadlogStats']

      <div class="edition-omniline">
        $:render_template("type/edition/publisher_line", edition)

        $if edition:
          $if edition.languages:
            <h4 class="language">
              $def lang_span(): <span itemprop="inLanguage">$:thingrepr(edition.languages)</span>
              $:_('Written in %(language)s', language=lang_span())
            </h4>
          $if edition.number_of_pages:
            <h4 class="year">&mdash;
              <span class="edition-pages"
                    itemprop="numberOfPages">$edition.number_of_pages</span> $_("pages")
            </h4>
      </div>

      $if work and work.description or edition and edition.description:
        <div class="book-description">
            <div class="book-description-content restricted-view">
                $if edition and edition.description:
                    $:sanitize(format(edition.description))
                $elif work and work.description:
                    $:sanitize(format(work.description))
            </div>
            $:macros.ReadMore("book-description")
        </div>
      $elif edition:
        <div class="book-description">
            <div class="book-description-content">
                <p class="workHelp">
                    $:_("This edition doesn't have a description yet. Can you <b><a href='%(url)s'>add one</a></b>?", url=edition.url('/edit')+"#about/about")
                </p>
            </div>
        </div>

    <div class="subjects">
        <div class="subjects-content restricted-view">
        $:macros.SubjectTags(work, ["Subjects"])
        </div>
        $:macros.ReadMore("subjects")
    </div>

      $:macros.EditionNavBar(work.edition_count)

      <p class="preview-languages">
        $ seen = set()
        $if previews:
          Previews available in:
          $for e in previews:
            $if e.languages[0].name not in seen:
              $ seen.add(e.languages[0].name)
              <a href="$work.key?edition=$(e.ocaid)">$e.languages[0].name</a>
      </p>

      <a name="editions-list" class="section-anchor"></a>

      $ component_times['EditionsTable'] = time()
      $:render_template("type/work/editions_datatable", work, editions=editions, edition=edition)
      $ component_times['EditionsTable'] = time() - component_times['EditionsTable']

      <a name="work-details" class="section-anchor"></a>
      <div class="tab-section work-info">
        <h2 class="work-title"><a href="$work.key">$work_title</a></h2>
          $if work and work.subtitle:
            <h3>
              $work.subtitle
            </h3>
          $if work and work.first_publish_year:
            <p class="first-published-date">
              $_("First published in %s", work.first_publish_year)
            </p>
        </h3>
        <hr>

        $ component_times['SubjectsTags'] = time()
        $:macros.SubjectTags(work, ["Subjects", "People", "Places", "Times"])
        $ component_times['SubjectsTags'] = time() - component_times['SubjectsTags']

        <hr>

        $if not work.excerpts and work.first_sentence:
          <h4>$_("First Sentence")</h4>
          <p class="largest" title=$_("First Sentence")><em>"$work.first_sentence</em>"</p>

        $if work.description:
          <h4>$_("Work Description")</h4>
          <div class="work-description">
            $:sanitize(format(work.description))
          </div>

        $if work.original_languages:
          <div class="sansserif smallest">$_("Original languages")</div>
          <!-- TODO: Double check that these language names are localized -->
          $', '.join(lang.name for lang in work.original_languages)<p>

        $if work.excerpts:
          <h4>$_("Excerpts")</h4>
          <div class="section">
              $for excerpt in work.excerpts:
                  <div class="excerpt addReadMore showlesscontent">
                      <div class="text">
                          $for line in excerpt.excerpt.split('\n'):
                              $line<br/>
                      </div>
                      <div class="attribution">
                          $if excerpt.pages:
                              $_("Page %(page)s", page=excerpt.pages),
                          $if excerpt.author:
                              $def excerpt_author_link(): <a href="$excerpt.author.key">$excerpt.author.displayname</a>
                              $:_("added by %(authorlink)s.", authorlink=str(excerpt_author_link()).strip()))
                          $else:
                              $_("added anonymously.")
                          $if excerpt.comment:
                              "<em>$excerpt.comment</em>"
                      </div>
                  </div>
          </div>

        $if work.links or (work.wikipedia and work.wikipedia.startswith("http")):
          <h4>$:_('Links <span class="gray small sansserif">outside Open Library</span>')</h4>
          <div class="section">
              <ul class="booklinks sansserif">
              $if work.wikipedia and work.wikipedia.startswith("http"):
                  <li><a href="$page.wikipedia">$_('Wikipedia')</a></li>
              $for link in work.links:
                  <li><a href="$link.url">$link.title</a></li>
              </ul>
          </div>

        $if work.edition_count > 1:
          $if (work.lc_classifications or work.dewey_number):
              <div class="section">
                  <h4 class="collapse">$_("Classifications")</h4>
                  <table class="meta"><tbody>
                  $if work.lc_classifications:
                      <tr><td class="title"><span class="title">$_('Library of Congress')</span></td>
                      <td><span class="object">$thingrepr(work.lc_classifications)</span></td></tr>
                  $if work.dewey_number:
                      <tr><td class="title"><span class="title">$_('Dewey')</span></td>
                      <td><span class="object">$thingrepr(work.dewey_number)</span></td></tr>
                  </tbody></table>
              </div>
      </div>

      <a name="edition-details" class="section-anchor"></a>
      <div class="tab-section edition-info">  
        $if not page.is_fake_record():
          $if page.type.key in ["/type/work", "/type/edition", "/type/author"]:
            $if edition and page.type.key in ["/type/work"]:
                $ edit_url = edition.url(suffix="/edit")
            $else:
                $ edit_url = page.url(suffix="/edit")
          $else:
            $ edit_url = page.key + "?m=edit"
          <div id="editButton">
            <!-- FIXME: accesskey / keyboard shortcut needs i18n -->
            <a class="linkButton larger" href="$edit_url" title="$_('Edit this template')"
              data-ol-link-track="CTAClick|Edit" accesskey="e">$_("Edit")</a>
          </div>
        $if not edition:
          <p>$_("No editions available")</p>
        $if edition:
          <h2 class="work-title" itemprop="name">$book_title</h2>
          $if edition.subtitle:
            <h3>
              $edition.subtitle
            </h3>
          $if edition.edition_name:
            <div class="work-line">
              $edition.edition_name
            </div> 
          $:render_template("type/edition/publisher_line", edition)    
          <hr>  
          $if edition.first_sentence:
            <div>
            <h3 class="collapse">$_("First Sentence")</h3>
            <p>"$(edition.first_sentence)"</p>
            </div>

          $if edition.description:
            <div class="section">
              <h3>$_("Edition Description")</h3>
              <div class="edition-description">
                <div class="addReadMore showlesscontent">
                  $:sanitize(format(edition.description))
                </div>
              </div>
            </div>

        $if edition:
          $ component_times['TableOfContents'] = time()
          $:macros.TableOfContents(edition, ocaid)
          $ component_times['TableOfContents'] = time() - component_times['TableOfContents']

          $if edition.notes or edition.series or edition.volume or edition.genres or edition.other_titles or edition.copyright_date or edition.translation_of or edition.translated_from:
            <div class="section">
                <h3>$_("Edition Notes")
                </h3>
                $if edition.notes:
                    $:format(edition.notes)
                <dl class="meta">
                    $:display_value(_("Series"), edition.series)
                    $:display_value(_("Volume"), edition.volume)
                    $:display_value(_("Genre"), edition.genres)
                    $:display_value(_("Other Titles"), edition.other_titles)
                    $:display_value(_("Copyright Date"), edition.copyright_date)
                    $:display_value(_("Translation Of"), edition.translation_of)
                    $:display_value(_("Translated From"), edition.translated_from)
                </dl>
            </div>

          $ classifications = edition.get_classifications().multi_items()
          $if classifications:
            <div class="section">
                <h3 class="list-header collapse">$_("Classifications")</h3>
                <dl class="meta">
                    $for name, values in classifications:
                        $:display_identifiers(values[0].label, values)
                </dl>
            </div>

          $ links = page.get_links()
          $if links:
            <div id="external-links">
              <h3 class="header">
                <span class="icon download"></span>
                <span class="head">$_('External Links')</span>
              </h3>
              <div class="panel">
                <ul class="booklinks sansserif">
                  $for link in links:
                    <li><a href="$link.url">$link.title</a></li>
                </ul>
              </div>
            </div>

          $ contributors = edition.get('contributors', [])
          $if contributors:
            <div class="section">
              <h3 class="collapse">$_("Contributors")</h3>
              <ul class="contributors">
                $for c in contributors:
                  $:display_contributor(c)
              </ul>
            </div>

          $if has_any("physical_format", "pagination", "physical_dimensions", "weight"):
            <div class="section">
                <dl class="meta">
                    <h3 class="list-header collapse">$_("The Physical Object")</h3>
                    $:display_value(_("Format"), edition.physical_format)
                    $:display_value(_("Pagination"), edition.pagination)
                    $:display_value(_("Number of pages"), edition.number_of_pages, itemprop="numberOfPages")
                    $:display_value(_("Dimensions"), edition.physical_dimensions)
                    $:display_value(_("Weight"), edition.weight)
                </dl>
            </div>


          <div class="section">
            <dl class="meta">
                <h3 class="list-header collapse">$_("ID Numbers")</h3>
                $:display_identifiers("Open Library", [storage(url=None, value=edition.key.split("/")[-1])])
                $for name, values in edition.get_identifiers().multi_items():
                    $ identifier_label = values[0].label
                    $if not (edition.is_in_private_collection() and identifier_label == 'Internet Archive'):
                        $:display_identifiers(identifier_label, values, itemprop=cond(name in ["isbn_10", "isbn_13"], "isbn", None))
            $:display_goodreads("Open Library", [storage(url=None, value=edition.key.split("/")[-1])])
            $for name, values in edition.get_identifiers().multi_items():
                $:display_goodreads(values[0].label, values)
            </dl>
          </div>
      </div>
    </div>

    <div class="workFooter">
      $# pages like /books/ia:foo00bar are fake records created from metadata API.
      $# Adding them to lists doesn't work. Disabling it to avoid any issues.
      $if "lists" in ctx.features and not page.is_fake_record():
        <h2 class="home-h2"><a href="$page.url()/lists">$_('Lists containing this Book')</a></h2>
        <div class="user-book-options">
          <div class="Tools tools-override">
            $if work:
              $ component_times['WorkListTime'] = time()
              $:render_template("lists/widget", work, include_header=False, include_widget=False)
              $ component_times['WorkListTime'] = time() - component_times['WorkListTime']

            $if edition:
              $ component_times['EditionListTime'] = time()
              $:render_template("lists/widget", edition, include_header=False, include_widget=False)
              $ component_times['EditionListTime'] = time() - component_times['EditionListTime']
          </div>
        </div>
    </div>
  </div>

  $ component_times['RelatedWorksCarousel'] = time()
  <div class="RelatedWorksCarousel" workId="$work.key.split('/')[-1]">
    <div class="hidden loadingIndicator">
        <figure>
        <img src="/images/ajax-loader-bar.gif">
        <figcaption style="
            justify-content: center;
            display: flex;
        ">Loading Related Books</figcaption>
        </figure>
    </div>
  </div>
  $ component_times['RelatedWorksCarousel'] = time() -component_times['RelatedWorksCarousel']

  $ component_times['HistoryTable'] = time()
  $:render_template("lib/history", page)
  $ component_times['HistoryTable'] = time() - component_times['HistoryTable']

  $ component_times['TotalTime'] = time() - component_times['TotalTime']

  $if query_param('debug'):
    <table>
      <thead>
        <tr>
          <th>Component</th>
          <th>Time</th>
          <th>%</th>
        </tr>
      </thead>
      <tbody>
        $for component in sorted(component_times.items(), key=lambda x: x[1]):
          <tr>
            <td>$component[0]</td>
            <td>$("%.2f" % component[1])</td>
            <td>$("%.2f" % (component[1] / component_times['TotalTime'] * 100.))</td>
          </tr>
      </tbody>
    </table>
</div>
